/*
 * Copyright 2002-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.aop.framework.autoproxy;

import org.springframework.aop.framework.AbstractAdvisingBeanPostProcessor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.lang.Nullable;

/**
 * Extension of {@link AbstractAutoProxyCreator} which implements {@link BeanFactoryAware},
 * adds exposure of the original target class for each proxied bean
 * ({@link AutoProxyUtils#ORIGINAL_TARGET_CLASS_ATTRIBUTE}),
 * and participates in an externally enforced target-class mode for any given bean
 * ({@link AutoProxyUtils#PRESERVE_TARGET_CLASS_ATTRIBUTE}).
 * This post-processor is therefore aligned with {@link AbstractAutoProxyCreator}.
 *
 * @author Juergen Hoeller
 * @since 4.2.3
 * @see AutoProxyUtils#shouldProxyTargetClass
 * @see AutoProxyUtils#determineTargetClass
 */
/*
1.   总结
	BeanFactory感知的后置处理器 - 扩展了AbstractAdvisingBeanPostProcessor，增加了对BeanFactory的感知能力
	目标类暴露机制 - 为每个代理Bean暴露原始目标类信息，支持外部强制的目标类代理模式
	与自动代理创建器对齐 - 设计上与AbstractAutoProxyCreator保持一致，提供相似的功能特性
2. 内部成员详解
	成员变量:
		beanFactory: ConfigurableListableBeanFactory，Spring Bean工厂引用
	核心方法:
		setBeanFactory() - 实现BeanFactoryAware接口，设置Bean工厂
		prepareProxyFactory() - 准备ProxyFactory，暴露目标类并处理代理目标类模式
		isEligible() - 检查Bean是否适合代理，排除原始实例
3. 类关系结构
ProxyConfig (class)
└── ProxyProcessorSupport (class)
    └── AbstractAdvisingBeanPostProcessor (abstract class)
        └── AbstractBeanFactoryAwareAdvisingPostProcessor (abstract class)
              └── MethodValidationPostProcessor (class)
			  └── PersistenceExceptionTranslationPostProcessor (class)
		      └── AsyncAnnotationBeanPostProcessor (class)
相关类关系说明:
AbstractAdvisingBeanPostProcessor: 父类，提供基本的Advisor应用功能
BeanFactoryAware: 实现此接口以获取BeanFactory引用
AutoProxyUtils: 工具类，提供自动代理相关的实用方法
MethodValidationPostProcessor: 唯一的具体实现类，用于方法验证
AbstractAutoProxyCreator: 相关的自动代理创建器，功能上与此类对齐
AbstractBeanFactoryAwareAdvisingPostProcessor在父类基础上增加了BeanFactory感知和目标类管理能力。


 */
@SuppressWarnings("serial")
public abstract class AbstractBeanFactoryAwareAdvisingPostProcessor extends AbstractAdvisingBeanPostProcessor
		implements BeanFactoryAware {

	@Nullable
	private ConfigurableListableBeanFactory beanFactory;


	@Override
	public void setBeanFactory(BeanFactory beanFactory) {
		this.beanFactory = (beanFactory instanceof ConfigurableListableBeanFactory ?
				(ConfigurableListableBeanFactory) beanFactory : null);
	}

	@Override
	protected ProxyFactory prepareProxyFactory(Object bean, String beanName) {
		if (this.beanFactory != null) {
			AutoProxyUtils.exposeTargetClass(this.beanFactory, beanName, bean.getClass());
		}

		ProxyFactory proxyFactory = super.prepareProxyFactory(bean, beanName);
		if (!proxyFactory.isProxyTargetClass() && this.beanFactory != null &&
				AutoProxyUtils.shouldProxyTargetClass(this.beanFactory, beanName)) {
			proxyFactory.setProxyTargetClass(true);
		}
		return proxyFactory;
	}

	@Override
	protected boolean isEligible(Object bean, String beanName) {
		return (!AutoProxyUtils.isOriginalInstance(beanName, bean.getClass()) &&
				super.isEligible(bean, beanName));
	}

}
